<?php

namespace App\Recharge;


use Exception;
use Throwable;
use GuzzleHttp\RequestOptions;
use Illuminate\Support\Facades\Http;
use App\Recharge\Bean\BasicInformation;
use App\Recharge\Bean\RequestResultBean;
use App\Models\Admin\InterfaceConfiguration;
use App\Recharge\Exceptions\SuspensionOfEnforcement;

class Service
{
    /**
     * @var Data
     */
    protected Data $data;

    /**
     * @param InterfaceConfiguration $config
     * @param BasicInformation $dataBean
     */
    public function __construct(protected InterfaceConfiguration $config, protected BasicInformation $dataBean)
    {
        $this->data = new Data($this->dataBean);
    }

    /**
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    protected function bean(): RequestResultBean
    {
        $bean = new RequestResultBean();
        $bean->setUrl($this->config->recharge_url);
        $bean->setMethod($this->config->method);
        if (!method_exists($this->data, $this->config->en)){
            throw new SuspensionOfEnforcement("未定义接口数据方法[".$this->config->en."]");
        }
        $bean->setRequest(call_user_func([$this->data, $this->config->en]));
        return $bean;
    }

    /**
     * 通用下单逻辑
     *
     * @param RequestResultBean $bean
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    protected function currencyApi(RequestResultBean $bean): RequestResultBean
    {
        try {
            // 请求的一些东西处理
            $options = $bean->getOptions();
            if (empty($options)) {
                $type = $this->config->api_data_format == 'json' ? RequestOptions::JSON : RequestOptions::FORM_PARAMS;
                $options = [$type => $bean->getRequest()];
            }
            // 请求
            $resp = Http::withoutVerifying()->timeout(60)->send($bean->getMethod(), $this->config->recharge_url, $options);
            $resp->successful() ? $bean->setResponse( $resp->body() ) : throw new Exception('请求失败');
            // 返回结果类
            return $bean;
        } catch (Throwable $e) {
            throw new SuspensionOfEnforcement($e->getMessage());
        }
    }

    /**
     * @param RequestResultBean $bean
     * @return RequestResultBean
     */
    protected function currencyRespHandle(RequestResultBean $bean): RequestResultBean
    {
        // 默认是通过的
        $result = true;
        // 转数组
        $resp = match ($this->config->api_sync_data_format) {
            "xml"   => xml2array($bean->getResponse()),
            default => json2array($bean->getResponse()),
        };
        $bean->setFormatResponse($resp);
        // 解析json 解析失败的话 就默认成功
        $judge = json2array($this->config->api_sync_judge);
        if (empty($judge)) {
            goto end;
        }
        foreach ($judge as $k => $v) {
            if (!isset($resp[$k]) || ($resp[$k] != $v)) {
                $result = false;
                break;
            }
        }
        if (!$result) {
            $errMessage = $this->config->title . '下单失败';
            if ($this->config->api_sync_err_key != "") {
                $errMessage = $resp[$this->config->api_sync_err_key] ?? $errMessage;
            }
            $bean->setErrorMessage($errMessage);
        }
        // 判断并返回
        end: return $bean->setResult($result);
    }

    /**
     * 通用下单并返回的逻辑
     *
     * @param RequestResultBean|null $bean
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    protected function currencyResp(?RequestResultBean $bean = null): RequestResultBean
    {
        $bean = $bean ?: $this->bean();
        // 下单
        $bean = $this->currencyApi($bean);
        // 返回
        return $this->currencyRespHandle($bean);
    }

    /*****              下单开始                *****/

    /**
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    public function shuoruan(): RequestResultBean
    {
        $bean = $this->bean();
        $bean->setOptions([
            RequestOptions::FORM_PARAMS => $bean->getRequest(),
            RequestOptions::DECODE_CONTENT => 'gzip, deflate',
        ]);
        // 返回
        return $this->currencyResp($bean);
    }

    /**
     * 商盟网下单
     *
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    public function shangmengwang(): RequestResultBean
    {
        $bean = $this->bean();
        $bean->setOptions([
            RequestOptions::QUERY => [
                'userName'  => $this->dataBean->getSupplierNum(),
                'sign'      => strtoupper( md5( json_encode($bean->getRequest()) .$this->dataBean->getSecretKey() ) ),
            ],
            RequestOptions::JSON => $bean->getRequest(),
        ]);
        return $this->currencyResp($bean);
    }

    /**
     * 百妙下单
     *
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    public function baimiao(): RequestResultBean
    {
        $bean = $this->bean();
        $bean->setOptions([
            RequestOptions::HEADERS => ['Authorization' => 'platformid="'.$this->dataBean->getSupplierNum().'"'],
            RequestOptions::JSON => $bean->getRequest(),
        ]);

        return $this->currencyResp($bean);
    }

    /*****              下单结束                 *****/

    /**
     * @param string $name
     * @param array $arguments
     * @return RequestResultBean
     * @throws SuspensionOfEnforcement
     */
    public function __call(string $name, array $arguments)
    {
        return $this->currencyResp();
    }
}
